package com.zhiwang.planet.widget

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.CompoundButton
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import com.zhiwang.planet.R
import com.zhiwang.planet.util.ColorStore
import com.zhiwang.planet.util.dp2px

class TagLayout(context: Context, attrs: AttributeSet) : ViewGroup(context, attrs), CompoundButton.OnCheckedChangeListener {

    private var checkable: Boolean = false
    private var tagTextColor: Int
    private var tagMarginBottom: Int
    private var tagMarginEnd: Int
    private var tagMarginTop: Int
    private var tagMarginStart: Int
    private var singleLine = false
    var checkedIndex = -1

    var checkedChangeListener: OnCheckedChangeListener? = null
    private var protectFromCheckChange = false

    private val checkChangeTracker = object : CompoundButton.OnCheckedChangeListener {
        override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {

            if (protectFromCheckChange)
                return

            protectFromCheckChange = true


            val prevCheckedIndex = checkedIndex

            val prevTag = findViewWithTag<CheckBox>(checkedIndex)
            prevTag?.isChecked = false


            checkedIndex = buttonView.tag as Int

            buttonView.isChecked = true

            checkedChangeListener?.onCheckedChange(checkedIndex, prevCheckedIndex)

            protectFromCheckChange = false

        }

    }

    fun getCheckedText() = findViewWithTag<CheckBox>(checkedIndex).text ?: ""

    fun check(index: Int) {
        val cb = findViewWithTag<CheckBox>(index)
        cb.isChecked = true
    }

    init {

        val ta = context.obtainStyledAttributes(attrs, R.styleable.TagLayout)


        this.tagMarginStart = ta.getDimensionPixelSize(R.styleable.TagLayout_tag_margin_start, 0)

        this.tagMarginTop = ta.getDimensionPixelSize(R.styleable.TagLayout_tag_margin_top, 0)

        this.tagMarginEnd = ta.getDimensionPixelSize(R.styleable.TagLayout_tag_margin_end, 0)

        this.tagMarginBottom = ta.getDimensionPixelSize(R.styleable.TagLayout_tag_margin_bottom, 0)

        this.tagTextColor = ta.getColor(R.styleable.TagLayout_tag_text_color, getColorAccent(context))

        this.singleLine = ta.getBoolean(R.styleable.TagLayout_singleLine, false)
        ta.recycle()
    }


    val TAG = "TagLayout"


    var spaceBetween = dp2px(context, 5f)


    val views = ArrayList<List<View>>()

    @SuppressLint("DrawAllocation")
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        views.clear()

        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)

        val hm = MeasureSpec.getMode(heightMeasureSpec)

        var h = 0

        var hmax = 0

        var restW = width
        var lineViews = ArrayList<View>()

        for (i in 0 until childCount) {
            val child = getChildAt(i)
            measureChild(child, widthMeasureSpec, heightMeasureSpec)
            if (restW < child.measuredWidth + spaceBetween) {
                if (singleLine) {
                    views.add(lineViews)
                    h += hmax + tagMarginTop
                    break
                }
                restW = width
                h += hmax + tagMarginTop
                hmax = 0
                views.add(lineViews)

                lineViews = arrayListOf()

                restW -= (child.measuredWidth + spaceBetween)
                lineViews.add(child)



                if (child.measuredHeight > hmax)
                    hmax = child.measuredHeight

                if (i == childCount - 1) {
                    views.add(lineViews)
                    h += hmax + tagMarginTop
                }
                continue
            } else {
                restW -= (child.measuredWidth + spaceBetween)
                lineViews.add(child)
                if (child.measuredHeight > hmax)
                    hmax = child.measuredHeight

                if (i == childCount - 1) {
                    views.add(lineViews)
                    h += hmax + tagMarginTop
                }
            }


        }

        setMeasuredDimension(width, h)

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

        var top = 0

        for (lineViews in views) {

            var left = 0

            for (v in lineViews) {

                v.layout(left, top, left + v.measuredWidth, top + v.measuredHeight)

                left += v.measuredWidth + spaceBetween
            }

            top += (lineViews.firstOrNull()?.measuredHeight ?: top) + tagMarginTop

        }


    }


    private fun getColorAccent(context: Context): Int {
        val ta = TypedValue()
        val re = context.obtainStyledAttributes(ta.data, intArrayOf(R.attr.colorAccent))
        return re.getColor(0, 0).also { re.recycle() }
    }


    fun setTags(tags: List<String>) {

        removeAllViews()
        tags.forEachIndexed { index, it ->
            addView(createTag(it, index))
        }
    }

    fun setCheckableTags(tags: List<String>) {
        this.checkable = true
        setTags(tags)
    }


    private fun createTag(text: String, index: Int): View {

        val textView = LayoutInflater.from(context).inflate(R.layout.tag, null) as CheckBox

        textView.text = text


        textView.tag = index

        if (checkable) {
            textView.setBackgroundResource(R.drawable.checkable_tag_bg)
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
            textView.setTextColor(ContextCompat.getColorStateList(context, R.color.checkable_tag_textcolor_selector))
            textView.isChecked = false
            textView.setOnCheckedChangeListener(checkChangeTracker)
        } else {
            textView.setBackgroundResource(R.drawable.tag_bg_nosolid)
            val color = ContextCompat.getColor(context, ColorStore.getTagColor(text))
            ViewCompat.setBackgroundTintList(textView, ColorStateList.valueOf(color))
            textView.setTextColor(color)
        }

        return textView
    }


    interface OnCheckedChangeListener {

        //        fun onItemChecked(index: Int)
//
//        fun onItemUnChecked(index: Int)
        fun onCheckedChange(checkedIndex: Int, prevCheckedIndex: Int)
    }

    override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {

    }

}